package com.nineclock.attendance.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.attendance.dto.AttendGroupDTO;
import com.nineclock.attendance.dto.AttendGroupPCExtraConfigDTO;
import com.nineclock.attendance.dto.AttendGroupPartDTO;
import com.nineclock.attendance.enums.AttendEnums;
import com.nineclock.attendance.mapper.AttendGroupMapper;
import com.nineclock.attendance.mapper.AttendGroupPartMapper;
import com.nineclock.attendance.pojo.AttendGroup;
import com.nineclock.attendance.pojo.AttendGroupPart;
import com.nineclock.attendance.service.AttendGroupService;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.feign.SysDepartmentFeign;
import com.nineclock.system.feign.SysOrganizationFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Slf4j
public class AttendGroupServiceImpl implements AttendGroupService {
    @Autowired
    AttendGroupMapper attendGroupMapper;
    @Autowired
    SysOrganizationFeign organizationFeign;
    @Autowired
    AttendGroupPartMapper attendGroupPartMapper;
    @Autowired
    SysDepartmentFeign departmentFeign;


    @Override
    public PageResult<AttendGroupDTO> queryAttendGroupPage(Integer page, Integer pageSize) {
        //先判断企业是否第一次使用考勤组
        LambdaQueryWrapper<AttendGroup> attendGroupQW = new LambdaQueryWrapper<>();
        attendGroupQW.eq(AttendGroup::getCompanyId, CurrentUserHolder.get().getCompanyId());
        Integer integer = attendGroupMapper.selectCount(attendGroupQW);

        //第一次使用 考勤组
        if (integer == 0) {
            //进行新增 默认考勤组
            AttendGroup attendGroup = new AttendGroup(
                    null,
                    "默认考勤组",
                    CurrentUserHolder.get().getCompanyId(),
                    null,
                    "09:00:00",
                    10,
                    30,
                    "12:00:00",
                    "14:00:00",
                    "17:00:00",
                    "1,1,1,1,1,0,0",
                    "普利商务中心",
                    "普利商务中心",
                    108.88995700000000000000,
                    34.37182600000000000000,
                    5000,
                    null,
                    CurrentUserHolder.get().getCompanyUserId(),
                    new Date(),
                    null,
                    null,
                    null,
                    null);
            attendGroupMapper.insert(attendGroup);
            //添加默认考勤组后, 所有部门都采用默认组
            List<Long> ids = organizationFeign.queryDepartmentIds().getData();
            for (Long id : ids) {
                AttendGroupPart attendGroupPart = new AttendGroupPart(
                        null,
                        attendGroup.getId(),
                        AttendEnums.ATTEND_OBJECT_TYPE_DEP.value(),
                        id,
                        AttendEnums.ATTEND_TYPE_YES.value());
                attendGroupPartMapper.insert(attendGroupPart);
            }
        }

        //非第一次使用
        //分页查询
        Page<AttendGroup> attendGroupPage = new Page<>(page, pageSize);
        LambdaQueryWrapper<AttendGroup> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AttendGroup::getCompanyId, CurrentUserHolder.get().getCompanyId());
        attendGroupMapper.selectPage(attendGroupPage, wrapper);
        //jopo ---> DTO
        List<AttendGroup> records = attendGroupPage.getRecords();
        List<AttendGroupDTO> attendGroupDTOS = BeanHelper.copyWithCollection(records, AttendGroupDTO.class);

        for (AttendGroupDTO attendGroupDTO : attendGroupDTOS) {
            //考勤组 ----查----> 考勤组关联表
            LambdaQueryWrapper<AttendGroupPart> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(AttendGroupPart::getAttendGroupId, attendGroupDTO.getId());
            List<AttendGroupPart> attendGroupParts = attendGroupPartMapper.selectList(wrapper1);

            //关联表分类 : 部门 员工分离
            //部门
            List<Long> collect1 = attendGroupParts.stream().filter(attendGroupPart -> {
                return attendGroupPart.getObjectType() == 1;
            }).map(attendGroupPart -> {
                return attendGroupPart.getObjectId();
            }).collect(Collectors.toList());
            //查询部门下的员工数
            Integer data = organizationFeign.queryUserCountByDepartmentIds(collect1).getData();  //todo

            //员工
            List<Long> collect2 = attendGroupParts.stream().filter(attendGroupPart -> {
                return attendGroupPart.getObjectType() == 2;
            }).map(attendGroupPart -> {
                return attendGroupPart.getObjectId();
            }).collect(Collectors.toList());

            System.err.println("===================================="+attendGroupDTO);
            attendGroupDTO.setMemberNum(data + (collect2 == null ? 0 : collect2.size()));

        }

        PageResult<AttendGroupDTO> pageResult = new PageResult<>();
        pageResult.setTotal(attendGroupPage.getTotal());
        pageResult.setTotalPage(attendGroupPage.getPages());
        pageResult.setRows(attendGroupDTOS);
        return pageResult;
    }

    @Override
    public void addAttendGroup(AttendGroupDTO attendGroupDTO) {
        //健壮性判断
        if (attendGroupDTO == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //DTO ---> jopo
        AttendGroup attendGroup = BeanHelper.copyProperties(attendGroupDTO, AttendGroup.class);
        //没有复制过来的手动传参
        attendGroup.setCompanyId(CurrentUserHolder.get().getCompanyId());
        //更新时间
        attendGroup.setCreateTime(new Date());
        attendGroup.setCreateUserId(CurrentUserHolder.get().getCompanyUserId());
        //工作日设置(类型不同)
        List<String> workdays = attendGroupDTO.getWorkdays();
        String join = StrUtil.join(",", workdays);
        attendGroup.setWorkdays(join);

        //特殊日期
        List<AttendGroupPCExtraConfigDTO> extraConfigs = attendGroupDTO.getExtraConfig();
        //获取 必须打卡日期
        List<String> collect = extraConfigs.stream().filter(extraConfig -> {
            return extraConfig.getRequiredAttend() == 0;
        }).map(extraConfig -> {
            return extraConfig.getSetDate();
        }).collect(Collectors.toList());
        //获取 无需打卡日期
        List<String> collect1 = extraConfigs.stream().filter(extraConfig -> {
            return extraConfig.getRequiredAttend() == 1;
        }).map(extraConfig -> {
            return extraConfig.getSetDate();
        }).collect(Collectors.toList());

        //获取 必须打卡日期
        attendGroup.setUnnecessaryTimeList(StrUtil.join(",", collect));
        //获取 无需打卡日期
        attendGroup.setNecessaryTimeList(StrUtil.join(",", collect1));
        attendGroupMapper.insert(attendGroup);


        //管理考勤组  和部门 ,员工之间的关系
        List<AttendGroupPartDTO> participates = attendGroupDTO.getParticipates();
        //先删除部门或者用户与考勤组的关系， 添加新的关系
        participates.forEach(attendGroupPartDTO -> {
            LambdaQueryWrapper<AttendGroupPart> attendGroupPartQw = new LambdaQueryWrapper<>();
            attendGroupPartQw.eq(AttendGroupPart::getObjectType, attendGroupPartDTO.getObjectType());
            attendGroupPartQw.eq(AttendGroupPart::getObjectId, attendGroupPartDTO.getObjectId());

            attendGroupPartMapper.delete(attendGroupPartQw);

            //删除后添加新的关系
            AttendGroupPart attendGroupPart = new AttendGroupPart();
            attendGroupPart.setAttendGroupId(attendGroup.getId());
            attendGroupPart.setAttendType(AttendEnums.ATTEND_TYPE_YES.value());
            attendGroupPart.setObjectType(attendGroupPartDTO.getObjectType());
            attendGroupPart.setObjectId(attendGroupPartDTO.getObjectId());

            attendGroupPartMapper.insert(attendGroupPart);
        });

        //不需要参加考勤组的处理
        List<AttendGroupPartDTO> notParticipates = attendGroupDTO.getNotParticipates();
        //先删除部门或者用户与考勤组的关系， 添加新的关系
        notParticipates.forEach(attendGroupPartDTO -> {
            LambdaQueryWrapper<AttendGroupPart> attendGroupPartQw = new LambdaQueryWrapper<>();
            attendGroupPartQw.eq(AttendGroupPart::getObjectType, attendGroupPartDTO.getObjectType());
            attendGroupPartQw.eq(AttendGroupPart::getObjectId, attendGroupPartDTO.getObjectId());
            //删除关系
            attendGroupPartMapper.delete(attendGroupPartQw);

            //删除后添加新的关系
            AttendGroupPart attendGroupPart = new AttendGroupPart();
            attendGroupPart.setAttendGroupId(attendGroup.getId());
            attendGroupPart.setAttendType(AttendEnums.ATTEND_TYPE_NO.value());
            attendGroupPart.setObjectType(attendGroupPartDTO.getObjectType());
            attendGroupPart.setObjectId(attendGroupPartDTO.getObjectId());

            attendGroupPartMapper.insert(attendGroupPart);
        });
    }

    @Override
    public AttendGroupDTO getAttendGroupByUserId() {
        //员工  ------查------>  考勤组
        LambdaQueryWrapper<AttendGroupPart> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AttendGroupPart::getObjectId,CurrentUserHolder.get().getCompanyUserId());
        wrapper.eq(AttendGroupPart::getObjectType,2);
        AttendGroupPart attendGroupPart = attendGroupPartMapper.selectOne(wrapper);
        if (attendGroupPart != null){
            AttendGroup attendGroup = attendGroupMapper.selectById(attendGroupPart.getAttendGroupId());
            AttendGroupDTO attendGroupDTO = BeanHelper.copyProperties(attendGroup, AttendGroupDTO.class);
            String workdays = attendGroup.getWorkdays();
            String[] split = workdays.split(",");
            attendGroupDTO.setWorkdays(Arrays.asList(split));
            return attendGroupDTO;
        }

        //部门ids -------查-------->  考勤组
        List<Long> ids = departmentFeign.queryDepartmentsByUserId(CurrentUserHolder.get().getCompanyUserId()).getData();
        if (ids != null){
            for (Long departmentid : ids) {
                LambdaQueryWrapper<AttendGroupPart> wrapper1 = new LambdaQueryWrapper<>();
                wrapper1.eq(AttendGroupPart::getObjectType, 1);
                wrapper1.eq(AttendGroupPart::getObjectId,departmentid);
                AttendGroupPart attendGroupPart1 = attendGroupPartMapper.selectOne(wrapper1);
                if (attendGroupPart1 != null){
                    AttendGroup attendGroup = attendGroupMapper.selectById(attendGroupPart1.getAttendGroupId());
                    AttendGroupDTO attendGroupDTO = BeanHelper.copyProperties(attendGroup, AttendGroupDTO.class);
                    String workdays = attendGroup.getWorkdays();
                    String[] split = workdays.split(",");
                    attendGroupDTO.setWorkdays(Arrays.asList(split));
                    return attendGroupDTO;
                }
            }

        }

        return null;
    }
}
